package com.fowo.api.flow.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fowo.api.common.model.R;
import com.fowo.api.flow.entity.FormGroups;
import com.fowo.api.flow.entity.ProcessTemplates;
import com.fowo.api.flow.entity.TemplateGroup;
import com.fowo.api.flow.mapper.FromGroupMapper;
import com.fowo.api.flow.mapper.TemplateGroupMapper;
import com.fowo.api.flow.model.TemplateGroupBo;
import com.fowo.api.flow.model.TemplateGroupVo;
import com.fowo.api.flow.model.vo.TemplateVo;
import com.fowo.api.flow.service.FromGroupService;
import com.fowo.api.flow.service.ProcessTemplateService;
import com.fowo.api.flow.service.TemplateGroupService;
import com.fowo.api.flow.utils.SpringContextHolder;
import com.fowo.api.user.model.JwtUserInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.flowable.common.engine.impl.util.CollectionUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.util.*;

/**
 * @fileName: FromGroupServiceImpl
 * @Description: 代码目的，作用，如何工作
 * @Author: pzh
 * @Date: 2023/4/6 0006 9:14
 */
@Slf4j
@Service
public class FromGroupServiceImpl extends ServiceImpl<FromGroupMapper, FormGroups> implements
        FromGroupService {
    @Resource
    private TemplateGroupService templateGroupService;

    @Resource
    private ProcessTemplateService processTemplateService;

    @Override
    public List<TemplateGroupVo> getFormGroups() {
        TemplateGroupMapper templateGroupMapper = SpringContextHolder.getBean(TemplateGroupMapper.class);
        List<TemplateGroupBo> allformAndGroups = templateGroupMapper.getAllFormAndGroups();
        Map<Integer, List<TemplateGroupBo>> coverMap = new LinkedHashMap<>();
        allformAndGroups.forEach(fg -> {
            List<TemplateGroupBo> bos = coverMap.get(fg.getGroupId());
            if (CollectionUtil.isEmpty(bos)) {
                List<TemplateGroupBo> list = new ArrayList<>();
                list.add(fg);
                coverMap.put(fg.getGroupId(), list);
            } else {
                bos.add(fg);
            }
        });
        List<TemplateGroupVo> results = new ArrayList<>();
        coverMap.forEach((key, val) -> {
            List<TemplateVo> templates = new ArrayList<>();
            val.forEach(v -> {
                if (ObjectUtils.isNotNull(v.getTemplateId())) {
                    templates.add(TemplateVo.builder()
                            .formId(v.getTemplateId())
                            .tgId(v.getId())
                            .remark(v.getRemark())
                            .formName(v.getTemplateName())
                            .icon(v.getIcon())
                            .isStop(v.getIsStop())
                            .lastUpdateTime(DateFormatUtils.format(v.getLastUpdateTime(), "yyyy年MM月dd日 HH时:mm分:ss秒"))
                            .background(v.getBackground())
                            .templateId(v.getTemplateId())
                            .logo(JSONObject.parseObject(v.getBackground(), new TypeReference<JSONObject>() {
                            }))
                            .build());
                }
            });
            results.add(TemplateGroupVo.builder().id(Long.valueOf(key)).name(val.get(0).getGroupName()).items(templates).build());
        });
        return results;
    }

    @Override
    public void formGroupsSort(List<TemplateGroupVo> groups) {
        int i = 0, j = 0;
        try {
            for (TemplateGroupVo group : groups) {
                this.updateById(FormGroups.builder()
                        .groupId(group.getId())
                        .sortNum(group.getId().equals(0) ? 999999 : i + 2)
                        .build());
                for (TemplateVo item : group.getItems()) {
                    templateGroupService.updateById(
                            TemplateGroup.builder()
                                    .id(item.getTgId())
                                    .groupId(group.getId())
                                    .templateId(item.getFormId())
                                    .sortNum(j + 1).build());
                    j++;
                }
                i++;
                j = 0;
            }
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            log.error("排序异常：" + e.getMessage());
        }

    }

    @Override
    public boolean updateFormGroupName(Integer id, String name) throws Exception {

        FormGroups formGroups = this.getById(id.longValue());
        if (ObjectUtils.isEmpty(formGroups)) {
            throw new Exception("分组不存在");
        }
        JwtUserInfo currentUser = JwtUserInfo.fromHeader();
        if (Objects.isNull(currentUser)) {
            throw new Exception("当前登录人获取失败");
        }

        formGroups.setGroupName(name.trim());
        formGroups.setLastUpdateUser(currentUser.getUserId());
        formGroups.setLastUpdateTime(new Date());
        return this.updateById(formGroups);
    }

    @Override
    public boolean createFormGroup(String name) throws Exception {
        LambdaQueryWrapper<FormGroups> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(FormGroups::getGroupName, name);
        if (this.count(lambdaQueryWrapper) > 0) {
            throw new Exception("分组名称 [" + name + "] 已存在");
        }

        JwtUserInfo currentUser = JwtUserInfo.fromHeader();
        if (Objects.isNull(currentUser)) {
            throw new Exception("当前登录人获取失败");
        }
        FormGroups formGroups = FormGroups.builder().groupName(name)
                .sortNum(1).createTime(new Date()).lastUpdateTime(new Date())
                .createUser(currentUser.getUserId()).lastUpdateUser(currentUser.getUserId()).build();
        return this.save(formGroups);
    }

    @Override
    public boolean deleteFormGroup(Integer id) throws Exception {

        FormGroups formGroups = this.getById(id.longValue());
        if (ObjectUtils.isEmpty(formGroups)) {
            throw new Exception("分组不存在");
        }

        return this.removeById(formGroups);
    }

    @Override
    public void updateForm(String templateId, String type, Integer groupId) throws Exception {
        boolean isStop = "stop".equals(type);


        ProcessTemplates build = ProcessTemplates.builder().templateId(templateId).isStop(isStop)
                .build();
        if ("using".equals(type) || isStop) {
            processTemplateService.updateById(
                    ProcessTemplates.builder().templateId(templateId).isStop(isStop).build());
        } else if ("delete".equals(type)) {
            processTemplateService.removeById(templateId);
            LambdaUpdateWrapper<TemplateGroup> lambdaQueryWrapper = new LambdaUpdateWrapper<>();
            lambdaQueryWrapper.eq(TemplateGroup::getTemplateId, templateId);
            lambdaQueryWrapper.set(TemplateGroup::getGroupId,null);
            templateGroupService.update(lambdaQueryWrapper);
        } else if ("move".equals(type)) {
            if (ObjectUtil.isNull(groupId)) {
                throw new Exception("分组不存在");
            }

            LambdaUpdateWrapper<TemplateGroup> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(TemplateGroup::getTemplateId, templateId);
            lambdaUpdateWrapper.set(TemplateGroup::getGroupId, groupId);
            templateGroupService.update(lambdaUpdateWrapper);
        } else {
            throw new Exception("分组不存在");
        }

    }
}
